#ifndef MSNETFRAME_H
#define MSNETFRAME_H
#include <libmslog/mstype.h>

typedef enum TCPOPT_KIND {
	TCPOPT_KIND_EOL = 0,		/* End of options */
	TCPOPT_KIND_NOP, 		/* NOP */
	TCPOPT_KIND_MSS, 		/* Maximum segment size */
	TCPOPT_KIND_WSO, 		/* Window scale option */
	TCPOPT_KIND_SACKP,		/* SACK permitted */
	TCPOPT_KIND_SACK,		/* SACK */
	TCPOPT_KIND_ECHO,
	TCPOPT_KIND_ECHOREPLY,
	TCPOPT_KIND_TSPOT,		/* Timestamp option */
	TCPOPT_KIND_POCP,		/* Partial Order Connection Permitted */
	TCPOPT_KIND_POSP,		/* Partial Order Service Profile */
	TCPOPT_KIND_UTO=28,		/* Timestamp option */
	/* Others are not used in the current OSF */
	TCPOPT_KIND_EMPTY = 255,
}TCPOPT_KIND;

typedef struct TCPHEADEROption{
	TCPOPT_KIND kind;
	ms_u08 len;
	ms_u08 val[256];
}TCPHEADEROption;
typedef struct TCPHEADEROPTIONContext{
	TCPHEADEROption tcpheader_opt[128];
	ms_u32 tcpheader_opt_num;
	ms_u32 tcpheader_opt_len;
}TCPHEADEROPTIONContext;
typedef struct TCPHEADERContext{
 	/*----20---*/
	ms_u16  source_port;
	ms_u16  dest_port;
	ms_u32  seq_num;
	ms_u32  ack_num;
	ms_u08  header_len:4;	// *4
	ms_u08  res:6;
	//flags
	ms_u08  urg:1;
	ms_u08  ack:1;
	ms_u08  psh:1;
	ms_u08  rst:1;
	ms_u08  syn:1;
	ms_u08  fin:1;
	ms_u16 win_size;
	ms_u16 check_sum;
	ms_u16 urgen_pointer;
 	/*----options---*/
	TCPHEADEROPTIONContext opt_ctt;
}TCPHEADERContext;
typedef struct UDPHEADERContext{
	ms_u16  source_port;
	ms_u16  dest_port;
	ms_u16  len;
	ms_u16 check_sum;
}UDPHEADERContext;
typedef struct IGMPHEADERContext{
	ms_u08  type;
	ms_u08  max_resp_time;
	ms_u16  check_sum;
	ms_u16  res;
	ms_u16  num_group_records;
	ms_u08  record_type;
	ms_u08  aux_data;
	ms_u16  num_src;
	ms_u32  multicast_addr;
	ms_u32  source_addr[20];
}IGMPHEADERContext;
typedef struct IPHEADERContext{
 	/*----16---*/
	ms_u08  version:4;	
	ms_u08  header_len:4;		//*4
	ms_u08  tos;	//tos
	ms_u16  total_len;
	ms_u16  id;	
	ms_u08  flags:3;	
	ms_u16  frag_offset:13;	
	ms_u08  ttl;	
	ms_u08  protocol;
	ms_u16  checksum;
	ms_u32  source_ip;
	ms_u32  dest_ip;
	//igmp-opt:router alert
	ms_u08 router_alert_type;
	ms_u08 router_alert_len;
	ms_u16 router_alert;	
//string
	ms_u08  str_protocol[128];
 	/*----options---*/
}IPHEADERContext;
typedef struct FRAMEContext{
	/*----14---*/	
	ms_u08 dest_mac[6];
	ms_u08 source_mac[6];
	ms_u16 type;
//string
	ms_u08 str_dest_mac[18];
	ms_u08 str_source_mac[18];
	ms_byte str_type[128];
}FRAMEContext;

typedef struct ARPHEADERContext{
	ms_u16 hardware_type;
	ms_u16 protocol_type;
	ms_u08 hardware_size;
	ms_u08 protocol_size;
	ms_u16 opcode;
	ms_u08 sender_mac[6];
	ms_u32  sender_ipaddr;
	ms_u08 target_mac[6];
	ms_u32  target_ipaddr;
}ARPHEADERContext;

typedef struct ETHERContext{
	FRAMEContext frame_ctt;
	union{
		IPHEADERContext ipheader_ctt;
		ARPHEADERContext arpheader_ctt;
	}ethertype_data;
	union{
		TCPHEADERContext tcpheader_ctt;
		UDPHEADERContext udpheader_ctt;
		IGMPHEADERContext igmpheader_ctt;
	}ipprotocol_data;
	
	ms_u08 data[9*1514];
	ms_u16 data_len;
	ms_u08 tmp[2052];
	ms_bool debug;
}ETHERContext;

typedef struct MSFRAMEFILTERContext{
	ms_bool flag_init;
	ms_bool flag_filter;
	ms_bool flag_filter_mac;
	ms_bool flag_filter_mac_source;
	ms_bool flag_filter_mac_dest;
	ms_bool flag_filter_protocol;
	ms_bool flag_filter_ip;
	ms_bool flag_filter_ip_source;
	ms_bool flag_filter_ip_dest;
	ms_bool flag_filter_port;
	ms_bool flag_filter_port_source;
	ms_bool flag_filter_port_dest;
	ms_u08  filter_protocol;
	ETHERContext ether_ctt;
}MSFRAMEFILTERContext;
typedef struct MSFRAMEFILTERConfig{
	ms_string filter_mac;
	ms_string filter_mac_source;
	ms_string filter_mac_dest;
	ms_string filter_protocol;
	ms_string filter_ip;
	ms_string filter_ip_source;
	ms_string filter_ip_dest;
	ms_s32 filter_port;
	ms_s32 filter_port_source;
	ms_s32 filter_port_dest;
//inner
	MSFRAMEFILTERContext msframefilter_ctt;
}MSFRAMEFILTERConfig;
typedef struct MSBULDTCPContext{
	ms_string str_dest_mac;
	ms_string str_source_mac;
	ms_string source_ip;
	ms_string dest_ip;
	ms_u16 source_port;
	ms_u16 dest_port ;
	ms_u32  seq_num;
	ms_u32  ack_num;
	ms_u08  urg:1;
	ms_u08  ack:1;
	ms_u08  psh:1;
	ms_u08  rst:1;
	ms_u08  syn:1;
	ms_u08  fin:1;
	TCPHEADEROPTIONContext opt_ctt;
}MSBULDTCPContext;
typedef struct MSBULDUDPContext{
	ms_byte interfaceout[128];
	ms_byte srcMac[128];
	ms_byte destMac[128];
	ms_byte srcIp[128];
	ms_byte destIp[128];
	ms_u16 srcPort;
	ms_u16 destPort;
}MSBULDUDPContext;
typedef enum ENUIGMPVer{
	IGMP_VERSION_UNKNOW	=0x00,
	IGMP_VERSION_1,
	IGMP_VERSION_2,
	IGMP_VERSION_3
}ENUIGMPVer;
typedef enum ENUIGMPCmd{
	IGMP_CMD_UNKNOW		=0x00,
	IGMP_CMD_QUERY,
	IGMP_CMD_REPORT,
	IGMP_CMD_LEAVE_GROUP
}ENUIGMPCmd;
typedef struct MSBULDIGMPContext{
	ms_string str_dest_mac;
	ms_string str_source_mac;
	ms_string source_ip;
	ms_string dest_ip;
	ENUIGMPVer igmp_ver;
	ENUIGMPCmd igmp_cmd;	//0-query;1-report;2-leave_group

	ms_bool flag_include;
	ms_u16 num_src;
	ms_byte source_addr[20][128];
}MSBULDIGMPContext;

#ifndef MSNETFRAME_C
extern ms_s32 
	msframe_api_buildArp( ETHERContext * ms_out pether_ctt, ms_string str_source_mac, ms_string sender_ipaddr, ms_string target_ipaddr,ms_byte *outbuf );
extern ms_u32 
	msframe_api_buildTcp(ETHERContext * ms_in pether_ctt,MSBULDTCPContext *pmsbuildtcp_ctt,ms_pbyte ms_out pether_pkt);
extern ms_u32 
	msframe_api_buildUdp(ETHERContext * ms_in pether_ctt,MSBULDUDPContext *pPUdp_ctt,ms_pbyte ms_out pether_pkt);
extern ms_u32 
	msframe_api_buildIgmp(ETHERContext * ms_in pether_ctt,MSBULDIGMPContext *pigmp_ctt_in,ms_bool flag_pppoe,ms_pbyte ms_out pether_pkt);
extern ms_u16 
	msframe_api_tcpChecksum(ETHERContext * ms_in pether_ctt,ms_pbyte ms_in  pether_pkt);	
extern ms_u16 
	msframe_api_udpChecksum(ETHERContext * ms_in pether_ctt,ms_pbyte ms_in  pether_pkt);	
extern ms_s08 
	msframe_api_doFrame( ETHERContext * ms_out pether_ctt,ms_pbyte ms_in frame_buf ,ms_bool flag_parseEtherInfo);
extern ms_bool 
	msframe_api_filterFrame(ms_string strdes, ms_pbyte ms_in frame_buf,MSFRAMEFILTERConfig*pmsframefilter_config);
extern ms_bool 
	msframe_api_is_ipArp(ETHERContext * ms_in pether_ctt);
extern ms_bool 
	msframe_api_isIpOrArp(ETHERContext * ms_in pether_ctt,ms_string ms_in  filter_sourceip,ms_string ms_in  filter_destip);
extern ms_bool 
	msframe_api_isTcp_dTos_ack(ETHERContext * ms_in pether_ctt,ms_string ms_in  filter_destip);
extern ms_bool 
	msframe_api_isTcp_dTos_close(ETHERContext * ms_in pether_ctt,ms_string ms_in  filter_destip);
extern ms_bool 
	msframe_api_isTcp_sTod_data(ETHERContext * ms_in pether_ctt,ms_string ms_in  filter_srcip);
extern ms_bool 
	msframe_api_isTcp(ETHERContext * ms_in pether_ctt);
extern ms_u32 
	msframe_api_buildTcpAck(ETHERContext * ms_in pether_ctt,ms_pbyte ms_in  pether_pkt);	
extern ms_u32 
	msframe_api_buildTcpData(ETHERContext * ms_in pether_ctt,ms_pbyte ms_in pether_pkt);	
#else
ms_u16 
	msframe_api_tcpChecksum(ETHERContext * ms_in pether_ctt,ms_pbyte ms_in  pether_pkt);	
ms_u16 
	msframe_api_udpChecksum(ETHERContext * ms_in pether_ctt,ms_pbyte ms_in  pether_pkt);	 
#endif

#endif